#region

using System;
using System.Collections.Generic;
using TimeDRODPOF.TDLib;
using VeeTileEngine2012;

#endregion

namespace TimeDRODPOF.TDComponents
{
    public class TDCWielder : Component
    {
        private bool _sheated;

        public TDCWielder(TDCMovement mMovementComponent, TDCDirection mDirectionComponent)
        {
            MovementComponent = mMovementComponent;
            DirectionComponent = mDirectionComponent;

            mMovementComponent.OnMovementSuccess += SyncWeaponWithWielder;
            mMovementComponent.OnMovementFail += SyncWeaponWithWielder;
        }

        public Entity WeaponEntity { get; set; }
        public TDCMovement MovementComponent { get; set; }
        public TDCWeapon WeaponComponent { get; set; }
        public TDCDirection DirectionComponent { get; set; }

        public bool Sheated
        {
            get { return _sheated; }
            set
            {
                _sheated = value;

                if (WeaponComponent == null || WeaponEntity == null) return;

                if (value)
                {
                    WeaponEntity.IsOutOfField = true;
                    if (WeaponComponent.OnUnEquip != null) WeaponComponent.OnUnEquip(this);
                }
                else
                {
                    WeaponEntity.IsOutOfField = false;
                    if (WeaponComponent.OnEquip != null) WeaponComponent.OnEquip(this);
                }
            }
        }

        public void SetWeapon(Entity mWeapon)
        {
            if (WeaponComponent != null) WeaponComponent.OnUnEquip.SafeInvoke(this);

            if (mWeapon == null)
            {
                WeaponEntity = null;
                WeaponComponent = null;
                Sheated = true;

                return;
            }

            WeaponEntity = mWeapon;
            WeaponComponent = mWeapon.GetComponent<TDCWeapon>();

            WeaponComponent.OnEquip += mWielder => MovementComponent.IgnoreEntities.Add(WeaponEntity);
            WeaponComponent.OnUnEquip += mWielder => MovementComponent.IgnoreEntities.Remove(WeaponEntity);

            if (Sheated)
                WeaponComponent.OnUnEquip.SafeInvoke(this);
            else
                WeaponComponent.OnEquip.SafeInvoke(this);

            SyncWeaponWithWielder();
        }

        public void SyncWeaponWithWielder()
        {
            if (Sheated) return;

            var wielderDirection = DirectionComponent.Direction;

            if (WeaponComponent.IsOutOfBounds)
            {
                WeaponComponent.IsOutOfBounds = false;
                WeaponEntity.IsOutOfField = false;
            }

            var oldDirection = WeaponEntity.GetComponent<TDCDirection>().Direction;
            WeaponEntity.GetComponent<TDCDirection>().Direction = wielderDirection;

            WeaponEntity.GetComponent<TDCRender>().IsLerped = oldDirection == DirectionComponent.Direction;

            var directionVector = DirectionComponent.DirectionVector;

            if (TDLMethods.WeaponMove(WeaponEntity, X + directionVector.X, Y + directionVector.Y))
                CheckHits();
        }

        public void CheckHits()
        {
            foreach (var entity in new List<Entity>(Field.GetEntitiesByTag(WeaponEntity.X, WeaponEntity.Y, TDLTags.HitByWeapon)))
                entity.GetComponent<TDCHitByWeapon>().HitAction.Invoke(WeaponComponent);
        }

        public override void Removed()
        {
            base.Removed();
            if (WeaponEntity != null) WeaponEntity.Destroy();
        }
    }
}